package com.icebartech.core.interceptor;

import com.alibaba.fastjson.JSON;
import com.icebartech.core.annotations.RequireLogin;
import com.icebartech.core.components.LoginComponent;
import com.icebartech.core.components.RedisComponent;
import com.icebartech.core.constants.IcebartechConstants;
import com.icebartech.core.constants.UserEnum;
import com.icebartech.core.controller.BaseController;
import com.icebartech.core.local.LocalUser;
import com.icebartech.core.local.UserThreadLocal;
import com.icebartech.core.utils.ResponseUtils;
import com.icebartech.core.vo.RespJson;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

/**
 * 登录拦截器，可以改成其他的权限校验框架
 * @author haosheng.wenhs
 *
 */
public class LoginInterceptor extends HandlerInterceptorAdapter {
    
    // private static Logger logger = LoggerFactory.getLogger("interceptor");
    
    @Autowired
    private RedisComponent redisComponent;
    
    @Autowired
    private LoginComponent loginComponent;
    
    /**
     * 清理资源，清理threadLocal
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
          throws Exception {
        
        // logger.info("-----enter login interceptor after completion ------");
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Object        controller    = handlerMethod.getBean();
        
        final RequireLogin requireLogin = handlerMethod.getMethodAnnotation(RequireLogin.class);
        if (controller instanceof BaseController) {
            if (requireLogin != null) {
                // LocalUser user = UserThreadLocal.getUserInfo();
                // logger.info("------ remove user thread local : {}", JSON.toJSONString(user));
                UserThreadLocal.removeUserInfo();
            }
        }
    }
    
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        
        String disable = redisComponent.getRedisCache(IcebartechConstants.SYSTEM_DISABLE, IcebartechConstants.SYSTEM_DISABLE);
        if ("y".equals(disable) && !"/api/base/sys/admin/setDisable".equals(request.getRequestURI()) && !"/base/sys/admin/setDisable".equals(request.getRequestURI())) {
            //返回json结果
            RespJson respJson = new RespJson();
            respJson.setStatus(IcebartechConstants.UNKNOWN_ERROR);
            respJson.setMsg("系统不可用！");
            ResponseUtils.renderJson(response, JSON.toJSONString(respJson));
            return false;
        }
        
        
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        Object        controller    = handlerMethod.getBean();
        // logger.info("-----enter login interceptor pre handle ------");
        if (controller instanceof BaseController) {
            BaseController baseController = (BaseController) controller;
            baseController.setRequest(request);
            baseController.setResponse(response);
        } else {
            // RespJson respJson = new RespJson();
            // respJson.setStatus(IcebartechConstants.UNKNOWN_ERROR);
            // respJson.setMsg("发生未知错误");
            // ResponseUtils.renderJson(response, JSON.toJSONString(respJson));
            // return false;
        }
        final RequireLogin requireLogin = handlerMethod.getMethodAnnotation(RequireLogin.class);
        if (requireLogin != null) {
            String sessionId = request.getParameter("sessionId");
            String userIdStr = null;
            UserEnum userEnum = null;
            do {
                if (StringUtils.isEmpty(sessionId) && !ArrayUtils.contains(requireLogin.userEnum(), UserEnum.guest)) {
                    break;
                }
                //如果是后台管理系统
                if (ArrayUtils.contains(requireLogin.userEnum(), UserEnum.admin)) {
                    userIdStr = redisComponent.getRedisCache(IcebartechConstants.ADMIN_SESSION_GROUP_KEY, sessionId);
                    if (StringUtils.isNotEmpty(userIdStr)) {
                        userEnum = UserEnum.admin;
                        // logger.info("admin user in redis : " + userIdStr);
                        //刷新登录信息
                        loginComponent.adminLogin(sessionId, Long.valueOf(userIdStr));
                        //注入UserCore对象
                        // logger.info("------ set admin user thread local : {}", userIdStr);
                        break;
                    }
                }
                if (ArrayUtils.contains(requireLogin.userEnum(), UserEnum.weixin)) {
                    //小程序登录和之前放cookie有所不同，小程序的登录流程请参见：https://mp.weixin.qq.com/debug/wxadoc/dev/api/api-login.html#wxchecksessionobject
                    
                    userIdStr = redisComponent.getRedisCache(IcebartechConstants.WEIXIN_SESSION_GROUP_KEY, sessionId);
                    if (StringUtils.isNotEmpty(userIdStr)) {
                        userEnum = UserEnum.weixin;
                        // logger.info("weixin user in redis : " + userIdStr);
                        //刷新过期
                        loginComponent.weixinLogin(sessionId, Long.valueOf(userIdStr));
                        //注入UserCore对象
                        // logger.info("------ set weixin user thread local : {}", userIdStr);
                        break;
                    }
                }
                if (ArrayUtils.contains(requireLogin.userEnum(), UserEnum.app)) {
                    //小程序登录和之前放cookie有所不同，小程序的登录流程请参见：https://mp.weixin.qq.com/debug/wxadoc/dev/api/api-login.html#wxchecksessionobject
                    userIdStr = redisComponent.getRedisCache(IcebartechConstants.APP_SESSION_GROUP_KEY, sessionId);
                    if (StringUtils.isNotEmpty(userIdStr)) {
                        userEnum = UserEnum.app;
                        // logger.info("app user in redis : " + userIdStr);
                        //刷新过期
                        loginComponent.appLogin(sessionId, Long.valueOf(userIdStr));
                        //注入UserCore对象
                        // logger.info("------ set app user thread local : {}", userIdStr);
                        break;
                    }
                }
                if (ArrayUtils.contains(requireLogin.userEnum(), UserEnum.h5_master)) {
                    //小程序登录和之前放cookie有所不同，小程序的登录流程请参见：https://mp.weixin.qq.com/debug/wxadoc/dev/api/api-login.html#wxchecksessionobject
                    
                    userIdStr = redisComponent.getRedisCache(IcebartechConstants.H5_MASTER_SESSION_GROUP_KEY, sessionId);
                    if (StringUtils.isNotEmpty(userIdStr)) {
                        userEnum = UserEnum.h5_master;
                        // logger.info("h5 master user in redis : " + userIdStr);
                        //刷新过期
                        loginComponent.h5MasterLogin(sessionId, Long.valueOf(userIdStr));
                        //注入UserCore对象
                        // logger.info("------ set h5 master user thread local : {}", userIdStr);
                        break;
                    }
                }
                if (ArrayUtils.contains(requireLogin.userEnum(), UserEnum.h5_slaver)) {
                    
                    userIdStr = redisComponent.getRedisCache(IcebartechConstants.H5_SLAVER_SESSION_GROUP_KEY, sessionId);
                    if (StringUtils.isNotEmpty(userIdStr)) {
                        userEnum = UserEnum.h5_slaver;
                        // logger.info("h5 slaver user in redis : " + userIdStr);
                        //刷新过期
                        loginComponent.h5SlaverLogin(sessionId, Long.valueOf(userIdStr));
                        //注入UserCore对象
                        // logger.info("------ set h5 slaver user thread local : {}", userIdStr);
                        break;
                    }
                }
                if (ArrayUtils.contains(requireLogin.userEnum(), UserEnum.guest)) {
                    // 匿名用户 设定空用户对象
                    UserThreadLocal.setUserInfo(null);
                    return true;
                }
            } while (false);
            
            if (StringUtils.isEmpty(userIdStr)) {
                //返回json结果
                RespJson respJson = new RespJson();
                respJson.setStatus(IcebartechConstants.RESULT_NOT_LOGIN);
                respJson.setMsg("您还没有登录，或者登录已超时，请重新登录！");
                ResponseUtils.renderJson(response, JSON.toJSONString(respJson));
                return false;
            }
            
            LocalUser user = new LocalUser();
            user.setSessionId(sessionId);
            user.setUserId(Long.valueOf(userIdStr));
            user.setUserEnum(userEnum);
            UserThreadLocal.setUserInfo(user);
        }
        return true;
    }
}
